// Copyright (c) 2022 Presto Labs Pte. Ltd.
// Author: juntang

#pragma once

#include <cstdio>
#include <map>
#include <memory>
#include <set>
#include <string>
#include <unordered_map>

#include <rapidjson/document.h>

#include "coin2/exchange/apollox/symbology/currency.h"
#include "coin2/exchange/apollox_base/api_util/rate_tracker.h"
#include "coin2/exchange/apollox_futures/symbology/product.h"
#include "coin2/exchange/base/order/order.h"

namespace coin2::exchange::apollox_futures::order_v1 {

class ApolloxFuturesParser : public base::order::BaseParser {
 public:
  using TransferType = coin::proto::TransferRequestProto::TransferType;

 public:
  ApolloxFuturesParser();
  const ParseResult& ParseRawMessage(const RawMessage& msg) override;
  AccountBalance ParseBalance(const JsonValue& doc) override;
  AccountPosition ParsePosition(const JsonValue& doc) override;
  bool ParseRawBalance(const JsonValue& doc, RawBalanceMap* raw_balance_map);
  bool ParseRawPosition(const JsonValue& doc, RawPositionMap* raw_position_map);

 private:
  void ParseListenKey();
  void ParseSubmitResponse();
  void ParseCancelResponse();
  void ParseRestOpenOrders();
  void ParseRestAllOrders();
  void ParseRestFillInfoList();
  void ParseRestAccountBalance();
  void ParseRestAccountPosition();
  void ParseTransfer();
  void ParseWsMessage();

  void ParseRestOrderInfoList();
  std::string ParseHeader(const std::shared_ptr<AsioHttpContext>&);
  bool ParseWsPosition(const JsonValue& doc, AccountPosition*);
  ProductOrderBundle ParseWsOrderInfoList(const JsonValue& data);
  ProductFillBundle ParseWsFillInfoList(const JsonValue& data);
  coin::proto::ProductOrderElement ParseRestOrderInfo(const JsonValue& data);
  bool ParseRawPositionFromWs(const JsonValue& doc, RawPositionMap* raw_position_map);

 private:
  bool is_query_historical_orders_{false};
  int64_t last_key_query_ts_{0};
  bool is_account_position_initialized_ = false;

  static std::map<std::string, TransferType> transfer_type_map_;

  bool is_account_cross_margin_cached_ = false;
};

}  // namespace coin2::exchange::apollox_futures::order_v1
